package com.itaq.cheetah.serviceA.config.jackson.deserialize;

import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.itaq.cheetah.serviceA.config.enums.EncryptType;
import com.itaq.cheetah.serviceA.config.exception.CustomException;
import com.itaq.cheetah.serviceA.config.factory.ObjectMapperFactory;
import com.itaq.cheetah.serviceA.config.web.AuthContextHolder;
import com.itaq.cheetah.serviceA.model.entity.SsoClientDetail;
import com.itaq.cheetah.serviceA.utils.SpringUtils;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author cheetah
 * @date 2022/7/25
 */
@Slf4j
@NoArgsConstructor
public class DecryptDeseserializer extends JsonDeserializer<Object> implements ContextualDeserializer {

    private JavaType contextualType;

    public DecryptDeseserializer(JavaType contextualType) {
        this.contextualType = contextualType;
    }

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        SsoClientDetail context = AuthContextHolder.getInstance().getContext();
//        log.debug("上下文信息：{}", JsonUtils.toPrettyString(context));
        String value = p.getValueAsString();
        EncryptType encryptType = EncryptType.get(context.getEncryptType());
        String s;
        switch (encryptType) {
            case AES:
                log.debug("解密方式：AES");
                AES aes = new AES(context.getPlatformSecret().getBytes(StandardCharsets.UTF_8));
                s = aes.decryptStr(Base64Utils.decodeFromString(value), StandardCharsets.UTF_8);
                break;
            case RSA:
                log.debug("解密方式：RSA");
                RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), SpringUtils.get("serviceA.rsa.privateKey"), null);
                s = new String(rsa.decrypt(Base64Utils.decodeFromString(value), KeyType.PrivateKey), StandardCharsets.UTF_8);
                break;
            default:
                throw new CustomException("加密方式配置错误");
        }
        return ObjectMapperFactory.getObjectMapper().readValue(s, contextualType);
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        JavaType contextualType = property.getType();
        return new DecryptDeseserializer(contextualType);
    }
}
